let hd = {
  name: 'Lee',
  age: 23,
  sex: 1,
  news: {
    title: 'No1',
    content: 'bababababbabababba',
  },
  other: [{ auther: 'kk', time: 22 }],
}

function defineRetive(obj, key, value) {
  Object.defineProperty(obj, key, {
    get() {
      console.log('获取')
      return value
    },
    set(newValue) {
      console.log('设置')
      value = newValue
      console.log(value)
    },
  })
}

function Observe(data) {
  if (typeof data !== 'object' || data == null) return

  if (Array.isArray(data)) {
    setArrayPrototype(data)
  }
  for (const [key, value] of Object.entries(data)) {
    Observe(value)
    defineRetive(data, key, value)
  }
}

// 设置数组对象的原型
// 目的：为新原型添加push
// 在新的push方法中添加拦截器
function setArrayPrototype(arr) {
  //添加新原型，新原型的原型为 Array.prototype
  let newPrototype = Object.create(Array.prototype)
  newPrototype.push = function (...args) {
    Array.prototype.push.apply(this, args)
    Observe(args)
  }
  arr.__proto__ = newPrototype
}
//对象属性拦截
hd.$set = function (key, value) {
  this[key] = value
  if (typeof value == 'object' && value != null) {
    observe(value)
  } else {
    defineRetive(this, key, value)
  }
}

Observe(hd)
hd.news.title = 'OKOKOKOK'
hd.other.push({ title: 'LOLOLO' })
hd.$set('url', 'booooom')
console.log(hd)

// console.log(hd.url)
